/**
 * request 用于发送及初步处理请求，
 * 包括，处理未登录，无权限，基本操作提示信息，以及loading动画，
 * loading 目前只能用默认配置 loadingConfig
 */

import axios from 'axios'
// import Promise from 'es6-promise'
import { Notification, Loading } from 'element-ui'
import { getPath } from './location'
import router from '../router'
import { log } from './index'

// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 8000 // 请求超时时间
})

// 处理请求超时
const processTimeout = (statusText, url) => {
  if (statusText.message.indexOf('timeout') > -1) {
    Notification({
      title: '请求超时',
      message: `<strong>请求地址：</strong>${url}`,
      dangerouslyUseHTMLString: true,
      type: 'error'
    })
  }
}

let loginOutStatus = 0 // 0 ready，1 pending, 2 done
// 处理未登录状态
const processLoginOut = (resp) => {
  if (loginOutStatus > 0) {
    return
  }
  let routeResolve = router.resolve(getPath()).route
  router.replace({name: 'Login', query: {from: routeResolve.query.from || routeResolve.fullPath}}, () => {
    loginOutStatus = 0
  })
  loginOutStatus = 1
}

const methodsMap = {
  delete: '删除',
  patch: '修改',
  put: '修改'
}
// 自定义操作，
const actionMap = {
  add: '添加',
  set: '设置'
}

/* 处理响应消息 */
const processResponseMsg = (resp) => {
  if (!resp) return
  const data = resp.data
  const msg = data.msg
  const code = data.status
  let config = resp.config
  let method = config.method
  let action = config.action
  let status = resp.status
  let methodText = methodsMap[method]
  let actionText = actionMap[action]
  if (code === 40000) {
    processLoginOut(resp)
    return
  }
  if (actionText) {
    if (status >= 200 && status < 300) {
      Notification({
        title: '操作成功',
        message: `${actionText}成功！`,
        type: 'success'
      })
    } else {
      Notification({
        title: '操作错误',
        message: `${actionText}失败！${msg}`,
        type: 'error'
      })
    }
    return
  }
  if (methodText) {
    if (status >= 200 && status < 300) {
      Notification({
        title: '操作成功',
        message: `${methodText}成功！`,
        type: 'success'
      })
    } else {
      Notification({
        title: '操作错误',
        message: `${methodText}失败！${msg}`,
        type: 'error'
      })
    }
    return
  }
  // 其他错误提示
  if (status < 200 || status >= 300) {
    Notification({
      title: '操作错误',
      message: `错误提示：${msg}`,
      type: 'error'
    })
  }
}

let globalLoading = []
let loadingTimer = []
let loadingConfig = {
  lock: true,
  text: 'Loading',
  spinner: 'el-icon-loading',
  background: 'rgba(255, 255, 255, 0.4)'
}
/**
 * @important config.loading [string]
 */
const processLoading = () => {
  _.each(loadingTimer, (timer) => {
    clearTimeout(timer)
  })
  _.each(globalLoading, (loading) => {
    loading.close()
  })
  loadingTimer = []
  globalLoading = []
}
// request拦截器
service.interceptors.request.use(
  (config) => {
    let cfg = config
    let loading = cfg.loading
    if (loading) {
      loadingTimer.push(setTimeout(() => {
        if ((typeof loading === 'string') && loading.indexOf('#') === 0) {
          globalLoading.push(Loading.service(_.assign({}, loadingConfig, {target: loading})))
        } else {
          globalLoading.push(Loading.service(loadingConfig))
        }
      }, 200))
    }
    return cfg
  },
  error => {
    log('err:' + error) // for debug
    return Promise.reject(error)
  }
)

// respone拦截器
service.interceptors.response.use(
  (response) => {
    let resp = response
    processResponseMsg(resp)
    processLoading(resp)
    log(`url: ${resp.config.url}\ndata:`, resp)
    return resp.data
  },
  error => {
    let err = error
    let resp = err.response
    processResponseMsg(resp)
    processLoading(resp)
    processTimeout(err, err.config.url)
    log('error:' + err + '\n' + JSON.stringify(err.config, 2, 2))// for debug
    return Promise.reject(err)
  }
)

export default service
